package com.haier.npt.filter.authorization;

import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.stereotype.Component;

import com.haier.npt.common.JsonResult;
import com.haier.npt.exception.BizBaseException;
import com.haier.npt.exception.ExceptionCode;
import com.haier.npt.security.client.SysPermisssionClient;
import com.haier.npt.security.domain.SysPermission;
import com.haier.npt.security.dto.RequestInfoDTO;

@Component
public class AuthProviderManager {

    @Autowired
    protected SysPermisssionClient sysPermisssionClient ;

    /**
     * 匹配服务名的正则表达式
     */
    protected String serviceIdPattern =  "(?<name>^.+)-(?<version>v.+$)" ;

    @Autowired
    private AbstractAuthProvider provider;

    private static final Logger logger = LoggerFactory.getLogger(AuthProviderManager.class);

    /**
     * 权限认证
     *
     * @return
     */
    public boolean doAuthorization(HttpServletRequest request, HttpServletResponse response, Route route) {
        // 获取当前url所需权限code
        Set<String> permissionCodeSet = this.getPermissionCode(request, route);
        if (permissionCodeSet != null && permissionCodeSet.size() > 0) {
            // 获取当前用户所拥有权限
            List<SysPermission> permissions = provider.onAuthorization(request, route);
            // 权限认证
            return this.isAccessAllowed(permissions, permissionCodeSet);
        }
        return true;
    }

    /**
     * 检验授权
     * @param userPermissions 当前用户的权限
     * @param urlPermissions url 需要的权限
     * @return
     */
    private boolean isAccessAllowed(List<SysPermission> userPermissions , Set<String> urlPermissions){
        if (urlPermissions == null || urlPermissions.isEmpty()) {
            return true;
        }
        for (int x = 0; x < userPermissions.size(); x++) {
            SysPermission sysPermission = userPermissions.get(x);
            if (urlPermissions.contains(sysPermission.getPermissionCode()) && sysPermission.isAvailable()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 返回url 需要的权限信息 ,返回null 说明不需要权限
     * @return
     */
    private Set<String> getPermissionCode(HttpServletRequest request , Route route){

        RequestInfoDTO requestInfoDTO = new RequestInfoDTO() ;

        if (route!=null) {
            String serviceId =  route.getLocation() ; //获取服务的id
            if(serviceId.matches(serviceIdPattern)){
                serviceId = StringUtils.substringBeforeLast(serviceId, "-");
            }
            //设置服务名
            requestInfoDTO.setServiceId(serviceId);
            requestInfoDTO.setMethod(request.getMethod());
            requestInfoDTO.setUrl(route.getPath());

            JsonResult<Set<String>> jsonResult = sysPermisssionClient.getPermissionCode(requestInfoDTO);
            if(jsonResult.getCode()==0 && jsonResult.getData()!=null){
                return jsonResult.getData() ;
            }else{
                logger.error("根据url获取权限code失败，【 服务名: {} , 方法：{} ， 访问路径:{} 】"  , serviceId,request.getMethod(),route.getPath());
                new BizBaseException(ExceptionCode.SYSTEM_ERROR); //系统异常
            }
        }
        return null ;
    }
}
